home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / mpp.exe / MOUSE.DOC < prev    next >
Text File  |  1992-10-07  |  52KB  |  1,261 lines

  1.  
  2.                           Mouse++ Version 4.0
  3.  
  4.                   Copyright (c)1992 by Carl Moreland
  5.                                10/06/92
  6.  
  7. -----------------------------------------------------------------------
  8.  
  9. Using the Mouse Class
  10.  
  11.     To  incorporate  the  mouse routines in your  program,  simply  add
  12. mouse.lib to your project or make file and #include mouse.h in any  mo-
  13. dule that calls a mouse function.  mouse.lib contains all the functions
  14. in mouse.cpp and cgc.cpp,  but the functions are separated into differ-
  15. ent object modules for greater efficiency.  Note that mouse.lib is com-
  16. piled for the large memory model.
  17.  
  18.     An instance of the Mouse class (there can only be ONE instance)  is 
  19. declared as extern in mouse.h,  so any file that #includes mouse.h will 
  20. automatically have access to the mouse.  You should NOT declare an  in-
  21. stance of the Mouse class in any part of your program. If you intend to
  22. change the mouse cursor, then you also need to #include cursor.h.
  23.  
  24.     When you link the mouse code into your program,  an instance of the
  25. mouse class is declared:
  26.  
  27.     Mouse mouse;
  28.  
  29. The  constructor Mouse::Mouse() calls the mouse driver  reset  function
  30. (all mouse driver functions are called via interrupt 33h)  and  initia-
  31. lizes  the flags exists, enabled, and visible.  exists is set to 1 if a
  32. mouse  was  found and should be checked first.  All other  mouse  class
  33. functions check exists before issuing interrupt 33h calls and abort  if
  34. it  is zero.  enabled is initially zero meaning the mouse is  disabled,
  35. and  visible is used by Show() and Hide() to keep track of  the  cursor
  36. visibility. An example of initializing the mouse is:
  37.  
  38.     #include "mouse.h"
  39.  
  40.     main()
  41.     {
  42.       if(mouse.Exists())        // check for mouse
  43.       {
  44.         mouse.Enable();        // enable the mouse
  45.         mouse.Show();        // display the cursor
  46.         ...
  47.       }
  48.     }
  49.  
  50. Again,  including  mouse.h automatically creates  an  instance  of  the
  51. class, so all you have to do is start using it.
  52.  
  53.     Once  the  mouse is initialized,  it may be necessary to  set  some
  54. parameters based on what video mode is being used. Strangely, the mouse
  55. driver  uses  pixel coordinates for both text and graphics  mode,  with
  56. (0,0)  being  the upper left hand corner of the screen,  and  (639,199)
  57. being  the default lower right hand corner.  This would be correct  for
  58. CGA graphics mode and for normal 80x25 text mode - for text mode,  this
  59. means that each character cell is treated as an 8x8 pixel array. If you
  60. are programming for the EGA or VGA as is the norm these days,  you will
  61. want  to change the y-limit of 199 for high resolution graphics and  43
  62. or 50 line text modes.  Failure to do this means that the mouse  cursor
  63. will not move below the 200th line in graphics mode, or the 25th row in
  64. text mode.  (Older mouse drivers might not support more than 200 lines.
  65. If  this is the case,  you will need to update your mouse driver.)  For
  66. 640x480 VGA graphics, you need to set the y-limit to (0,479) by calling
  67. yLimit(0,479).  For  43 or 50 line text mode,  the mouse  driver  still
  68. treats  each character cell as an 8x8 pixel array,  so you need to  set
  69. the  y-limit  to (0,349) or (0,399), respectively.  Since  the  default
  70. width  of 640 pixels is correct for most video modes,  xLimit() is only
  71. necessary  when using SuperVGA graphics.  (See the section on  SuperVGA
  72. support) Both xLimit() and yLimit() can also be used to limit the mouse
  73. cursor to a small portion of the screen, such as a menu.
  74.  
  75.     You  may want to use a mouse cursor other than the default  cursor.
  76. To do this,  call the function SetCursor() with the appropriate  cursor
  77. name.  Many programs (especially graphics) will use  several  different
  78. cursors  depending on the location of the mouse (such as an  arrow  for
  79. menus  and  an i-beam for text) or the particular function  being  pro-
  80. cessed (such as an hourglass for wait).  Several cursors are predefined
  81. in the file cursor.h.  To use them,  simply include this header file in
  82. whatever  module changes the cursor.  For more information on  cursors,
  83. see the Mouse Cursors section.
  84.  
  85.     Finally,  you may want to set the motion parameters,  which include
  86. the  mickey-to-pixel ratio and the double-speed threshold.  The mickey-
  87. to-pixel  ratio  is set by MickToPix() and defines how many mickeys  it
  88. takes  to move the mouse 8 pixels.  (A mickey is single count of  mouse
  89. motion. Most mice are 200 "dots-per-inch", which means that one inch of
  90. movement  results in 200 mickeys.)  If both the x and y parameters  are
  91. set  to 8,  then there will be a one-to-one correlation  between  mouse
  92. motion  and cursor motion.  The default values are 8 in the  horizontal
  93. direction and 16 for the vertical.  The vertical value of 16 means  the
  94. mouse must be moved twice as far vertically as horizontally to  get the
  95. same cursor movement.  This is fine for text mode where the  equivalent
  96. screen  resolution  of 640x200 results in an  equivalent  pixel  aspect
  97. ratio of 2.4-to-1.  In EGA/VGA graphics mode the y-direction will  seem
  98. noticeably  slower,  particularly for 640x480 which has  an  equivalent
  99. pixel  aspect ratio of 1-to-1.  A vertical ratio of 8 will  cure  this.
  100. The lower the ratio, the farther the cursor will move for a given mouse
  101. movement.  Setting either ratio lower than 8 means that the cursor can-
  102. not be located on every pixel. For example, setting the ratio to 4 will
  103. cause  the cursor to move 2 pixels for every mickey.  The  double-speed
  104. threshold  is set by a call to SetSpeedThreshold().  When the speed  of
  105. the mouse (in mickeys per second) exceeds the speed parameter passed to
  106. SetSpeedThreshold(), the motion speed of the cursor will double. A com-
  107. plete initialization might look like this:
  108.  
  109.     #include "mouse.h"
  110.     #include "cursor.h"
  111.  
  112.     main()
  113.     {
  114.       { initialize screen };
  115.       if(mouse.Exists())
  116.       {
  117.         mouse.SetCursor(cross);
  118.         mouse.yLimit(0,479);    // VGA 640x480
  119.         mouse.MickToPix(8,8);
  120.         mouse.SetSpeedThreshold(32);
  121.         mouse.Enable();
  122.         mouse.Show();
  123.         ...
  124.       }
  125.     }
  126.  
  127.     The  mouse should be reset before your program terminates  so  that
  128. the  calling program does not inherit any strange parameters.  This  is
  129. particularly true of the event handler. Because it is an interrupt rou-
  130. tine,  failure to reset the mouse could lead to a system crash  if  the
  131. handler is still pointing to the address of what used to be your  hand-
  132. ler routine. The destructor Mouse::~Mouse() first resets the mouse sta-
  133. tus by calling function 00h, and then restores the original event hand-
  134. ler with function 14h.
  135.  
  136. -----------------------------------------------------------------------
  137.  
  138. Reading the Mouse
  139.  
  140.     Most  of the standard mouse functions stuff any return  values  di-
  141. rectly  into the class variables and have a return type void.  This  is
  142. because many mouse functions return more than one item of  information.
  143. You  can then use the appropriate inline function to read the  required
  144. private  variable.  To check for the mouse position, for instance,  you
  145. would call Position() followed by either x() or y(), or both, such as:
  146.  
  147.     for(;;)
  148.     {
  149.       mouse.Position();
  150.       if(mouse.x() > 320 || mouse.y() > 100)
  151.         do_something();
  152.     }
  153.  
  154. This  method has the advantage of capturing both the x and y  positions
  155. with  a single function call,  and those variables can then be read  at
  156. your  leisure.  However,  we generally don't care where  the  mouse  is
  157. located  unless  a button event that we are looking for  has  occurred.
  158. Position() also returns the status of the mouse buttons, so we can also
  159. check them:
  160.  
  161.     for(;;)
  162.     {
  163.       mouse.Position();
  164.       if(mouse.LB_Dn())        // check for left button down
  165.       {
  166.         if(mouse.x() > 320 || mouse.y() > 100)
  167.           do_something();
  168.       }
  169.       else
  170.         do_something_else();
  171.     }
  172.  
  173. This  loop will continuously check to see if the left button  has  been
  174. pressed.  If the do_something_else() code is slow then there is a  pos-
  175. sibility  that a button press could be missed since Position()  returns
  176. the  real-time status of the mouse.  That is, during execution  of  the
  177. do_somethin